/*
 * The Open Source Unix Installer
 *
 * The MIT License
 *
 * Copyright 2011-2012 Andrey Pudov.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/*
 * @author  Andrey Pudov    <andrey@andreypudov.com>
 * @version 0.00.00
 * @name    init.c
 * @date:   Feb 11, 2011
 */

#include "init.h"

/* the legitimate option characters */
static const char *_opt_string = "hv";
/*
 * -h print help (this message) and exit
 * -v print version information and exit
 */

/* the legitimate long option array */
static const struct option _long_opts[] = {
    {"help",     no_argument,       NULL, 'h'},
    {"log-file", required_argument, NULL,  0},
    {"version",  no_argument,       NULL, 'v'},
    {NULL,       no_argument,       NULL,  0}
};
/*
 * --help            print help (this message) and exit
 * --log-file <file> write log messages to <file>
 * --version         print version information and exit
 */

/* private code declaration */
static void _installer_init_set_default();
static void _installer_init_parse(int argc, char **argv);

static void _installer_init_arg_handler_help(char invalid_option);
static void _installer_init_arg_handler_logfile(const char *file_name);
static void _installer_init_arg_handler_version();

/* public code definition */
void installer_init_init(int argc, char **argv) {
    /* set default values to core variables */
    _installer_init_set_default();

    /* parse user arguments */
    _installer_init_parse(argc, argv);
}

/* private code definition */
void _installer_init_set_default() {
    Dictionary *dictionary = installer_dictionary_new();
    Logger     *logger     = NULL;
    Properties *properties = installer_properties_new();

    /* modifiable, null-terminated character array */
    char template[] = "/tmp/installer-init_set_default.XXXXXX";

    FILE *file_pointer = NULL;

    int dictionary_index = 0;
    int properties_index = 0;
    int file_descriptor  = 0;

    /* goint through dictionary list until NULL key */
    while (dictionary_default[dictionary_index].key) {
        installer_dictionary_set(&dictionary, 
                                 dictionary_default[dictionary_index].key,
                                 dictionary_default[dictionary_index].value);

        dictionary_index++;
    }

    /* going through properties list until NULL key */
    while (properties_default[properties_index].key) {
        installer_properties_set(&properties,
                                 properties_default[properties_index].key,
                                 properties_default[properties_index].value);

        properties_index++;
    }

    /* define temporary log file */
    file_descriptor = mkstemp(template);
    file_pointer    = fdopen(file_descriptor, "w");
    if ((file_descriptor == -1) || (file_pointer == NULL)) {
        fprintf(stderr, "[ERROR|%s] %s - %s\n",
                "_installer_set_default", template, strerror(errno));
    }
    logger = installer_logger_new(file_pointer);

    installer_core_set_dictionary(dictionary);
    installer_core_set_logger(logger);
    installer_core_set_properties(properties);
}

void _installer_init_parse(int argc, char **argv) {
    /* the option character */
    int opt = 0;

    /* the index of the long option relative to _long_opt */
    int long_index = 0;

    /* prevent the error message */
    opterr = 0;
   
    /* going through options until the end */ 
    while ((opt = getopt_long(argc, argv, _opt_string, _long_opts, &long_index))
            != -1) {
        switch (opt) {
            case 'h':
                _installer_init_arg_handler_help(-1);
                break;
            case 'v':
                _installer_init_arg_handler_version();
                break;
            case 0:     /* long option without a short arg */
                if (strcmp("log-file", _long_opts[long_index].name) == 0) {
                    _installer_init_arg_handler_logfile(optarg);
                }
                break;
            default:
                _installer_init_arg_handler_help((char) optopt);
                break;
        }
    }
}

void _installer_init_arg_handler_help(char invalid_option) {
    printf("Usage: installer [options]\n" \
        "  -h or --help          print help (this message) and exit\n" \
        "  --log-file <file>     write log messages to <file>\n" \
        "  -v or --version       print version information and exit\n");

    exit((invalid_option == -1) ? EXIT_SUCCESS : EXIT_FAILURE);
}

void _installer_init_arg_handler_logfile(const char *file_name) {
    Logger *logger;

    /* delete already exists logger */
    if ((logger = installer_core_get_logger()) != NULL) {
        installer_logger_delete(logger);
    }

    /* create new instance of logger */
    logger = installer_logger_new(fopen(file_name, "w"));

    installer_core_set_logger(logger);
}

void _installer_init_arg_handler_version() {
    printf("installer version 0.00.00 %s %s\n", __DATE__, __TIME__);
    printf("Copyright (C) 2011-2012 Andrey Pudov. All rights reserved.\n");

    exit (EXIT_SUCCESS);
}
